package com.qcby.demo.proxyaop.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @className: SelfRecordsAop
 * @description:
 * @author: lxt
 * @create: 2021-05-13 22:27
 **/
@Aspect
@Slf4j
@Component
public class SelfRecordsAop {




    @Autowired
    private HttpServletRequest httpServletRequest;


    //定义切点，注解作为切入点
    @Pointcut("@annotation(com.qcby.demo.proxyaop.aop.SelfRecords)")
    public void selfRecordsPoinCut() {

    }


    /**
     * before 目标方法执行前执行，前置通知  ==>token验证
     * after 目标方法执行后执行，后置通知  =》记录操纵日志
     * after returning 目标方法返回时执行 ，后置返回通知 =》记录操纵日志
     * after throwing 目标方法抛出异常时执行 异常通知   ==>记录异常日志
     * around 在目标函数执行中执行，可控制目标函数是否执行，环绕通知 ==>token验证
     */

    @Before("selfRecordsPoinCut()")
    public void before(){
        log.info("before................通知");
    }
    @After("selfRecordsPoinCut()")
    public void after(){
        log.info("After................通知");
    }

    @AfterReturning("selfRecordsPoinCut()")
    public void afterReturning(){
        log.info("AfterReturning................通知");
    }

    @AfterThrowing(pointcut  = "selfRecordsPoinCut()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint,Exception ex){

        log.info("AfterThrowing................通知");
    }

    /**
     * 可控制目标函数是否执行
     */
    @Around("selfRecordsPoinCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("Around................通知");
        log.info("进入Around通知....");
        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();



//        String token = httpServletRequest.getHeader("token");
        //获取注解信息
        SelfRecords viewRecords = method.getAnnotation(SelfRecords.class);

        String idValue = viewRecords.id();
        log.info("viewRecords：{}",viewRecords);
        log.info("idValue的值为：{}",idValue);
        Long id = null;

        //获取切入点方法参数
        Object[] objects = joinPoint.getArgs();
        String[] paramNames =  signature.getParameterNames();
        for (int i =0;i<paramNames.length;i++){
            if (Objects.equals(idValue,paramNames[i]) && objects[i] != null){
                id = Long.valueOf(objects[i].toString());
            }
        }
        log.info("id的值为：{}",id);
        /**
         * 进行业务操作
         */
        Object r = joinPoint.proceed();



        return r;
    }



}
